package com.hisense.hiioc.hismartplate.server;

import com.hisense.hiioc.hismartplate.constants.ServerConstants;
import com.hisense.hiioc.hismartplate.server.base.BaseServer;
import com.hisense.hiioc.hismartplate.server.handler.AuthHandler;
import com.hisense.hiioc.hismartplate.server.handler.MessageHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author: almo
 * @Date: 2018/12/5 下午2:21
 * @Version 1.0
 */
public class CoreServer extends BaseServer {

    private ScheduledExecutorService scheduledExecutor;
    private CoreManager coreManager = CoreManager.getInstance();

    @Override
    public void start() {
        serverBootstrap.group(coreLoopGroup, workLoopGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_BACKLOG, 2 << 10)
                .localAddress(new InetSocketAddress(ServerConstants.DEFAULT_PORT))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(defaultEventLoopGroup,
                                new HttpServerCodec(),
                                new HttpObjectAggregator(2 << 10),
                                new ChunkedWriteHandler(),
                                new IdleStateHandler(60, 0, 0),
                                new AuthHandler(),
                                new MessageHandler());
                    }
                });

        try {
            channelFuture = serverBootstrap.bind().sync();
            InetSocketAddress addr = (InetSocketAddress) channelFuture.channel().localAddress();
            logger.info("WebSocketServer start success, port is:{}", addr.getPort());

            if (scheduledExecutor == null)
                scheduledExecutor = Executors.newScheduledThreadPool(2);

            scheduledExecutor.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    coreManager.scanNotActiveChannel();
                }
            }, 3, 60, TimeUnit.SECONDS);

            scheduledExecutor.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    coreManager.broadcastPing();
                }
            }, 3, 50, TimeUnit.SECONDS);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void shutDown() {
        if (scheduledExecutor != null)
            scheduledExecutor.shutdownNow();
        super.shutDown();
    }
}
